//Darius Smith
//DA5 part 3
//This project code will control the position of a servo motor using 
//a potentiometer. It allows the motor to turn from 0 to 180 degrees
//The following conversions represent the angle for a specific adc value
//0 = 600		45 = 1025		90 = 1450		135 = 1875		180 = 2300

#define F_CPU 8000000UL	//XTAL = 8MHZ

#include <avr/io.h>
#include <stdio.h>
#include <avr/interrupt.h>
#include <util/delay.h>


void printStringToScreen(char *sentence)//function to print output
	{	
	while ((*sentence !='\0'))
		{
		while(!(UCSR0A&(1<<UDRE0)));
			UDR0 = *sentence;
		sentence++; 
		}
	}

int main(void)
	{
	int ADC_init = 0;		//adc initial variable
	int ADC_new = 0;		//adc value after calculations
	char outputString[999];	//holds output string
	double adc_val;			//adc value as floating
	int ocrV;				//
		
	DDRC = 0x00;		// sets all c ports to inputs
	DDRB = 0xFF;		// sets all b port to outputs
	ADCSRA = 0x82;		// make adc enable and select clock/128
	ADMUX = 0x00;		// 5.0 avcc and adc0 as input right justified
	UCSR0B = 0x08;		// TXEN0, bit 3, decimal value 8, is set high to enable the ATMega328p to transmit information, serially.
	UCSR0C = 0x06;		// UCSZ01 and UCSZ00, decimal values 4 and 2, are set high so that
	UBRR0 = 0x0033;		
	ICR1 = 19999;
	TCCR1A |= 0x42;		//(1000 0010) clears OC1A on compare match
	TCCR1B |= 0x1A;		//(0001 1010) fast PWM mode
		
	while(1)
		{
		ADCSRA |= (1<<ADSC);
		while ((ADCSRA & (1<<ADIF)) == 0)
			{
			}
		
		ADC_new = ADC_init - ADC;
		
		if((ADC_new > 15) || (ADC_new < -15))
			{
			ADC_init = ADC;
			}

		if(ADC_init < 50)
			{
			ocrV = 600;
			}
		else if(ADC_init > 540)
			{
			ocrV = 2300;
			}
		else
			{
			adc_val = ((ADC_init - 70) * 3.62) + 600;
			ocrV = adc_val;
			}
		
		OCR1A = ocrV;
		snprintf(outputString,sizeof(outputString), "New ADC: %3d\r\n\n", ADC_init);
		printStringToScreen(outputString);
		}
}